package apportioner

import (
	// "bp/cache"
	sqlc "bp/db/sqlc"
	"bp/internal/nsqserver/producer"
	"bp/internal/util"
	"context"
)

type ApportionTransactionID int64

func (s *ApportionerComServiceImp) runApportionWorkers(max uint32) (chans []chan ApportionTransactionID) {
	for i := 0; i < int(max); i++ {
		ch := make(chan ApportionTransactionID)
		s.slog.Infof("分摊任务 worker:%d", i+1)
		go s.doApportionTask(ch)
		chans = append(chans, ch)
	}
	return
}

func (s *ApportionerComServiceImp) doApportionTask(ch <-chan ApportionTransactionID) {
	ctx := context.Background()
	var apportionmentOfOrderDetailPtrs []*producer.ApportionmentOfOrderDetail
	for transactionID := range ch {
		// 这里开始真正的执行分摊
		offTransactionPtr, err := s.entityHub.OffTransactionService.GetTransactionPtr(ctx, s.dao.Q, int64(transactionID))
		if err != nil {
			s.slog.Errorf("获取交易(%d)GetTransactionPtr err:%s", transactionID, err.Error())
			return
		}

		err = s.dao.NewTxRunner().SqlcExecTx(ctx, func(q *sqlc.Queries) (err error) {
			apportionmentOfOrderDetailPtrs, err = s.apportionOff(ctx, q, offTransactionPtr)
			if err != nil {
				return
			}
			return
		})
		if err != nil {
			s.slog.Errorf("ApportionOff of transactionID(%d) err:%s", transactionID, err.Error())
			continue
		}
		s.slog.Infof("transactionID(%d)分摊完成 ok", transactionID)

		// 这里将分摊记录广播给其他监听者
		err = s.dao.NewTxRunner().SqlcExecTx(ctx, func(q *sqlc.Queries) (err error) {
			err = s.notifyOffApportionment(ctx, q, offTransactionPtr, apportionmentOfOrderDetailPtrs)
			if err != nil {
				return
			}
			return
		})
		if err != nil {
			s.slog.Errorf("NotifyOffApportionment of transactionID(%d) err:%s", transactionID, err.Error())
			continue
		}
		s.slog.Infof("transactionID(%d)分摊记录已广播 ok", transactionID)
	}
}

func (s *ApportionerComServiceImp) GetApportionWorker() (ch chan<- ApportionTransactionID) {
	upper := len(s.apportionChans) - 1
	ch = s.apportionChans[util.RandomInt(0, int32(upper))]
	if ch != nil {
		return
	}
	return
}
